package com.zdp.leetcodeMiddle;


import java.util.LinkedList;

/*
* 题目描述：
* 给你一个字符串 s ，请你去除字符串中重复的字母，使得每个字母只出现一次。需保证 返回结果的字典序最小（要求不能打乱其他字符的相对位置）。
注意：该题与 1081 https://leetcode-cn.com/problems/smallest-subsequence-of-distinct-characters 相同
示例 1：
输入：s = "bcabc"
输出："abc"
示例 2：
输入：s = "cbacdcbc"
输出："acdb"
提示：
1 <= s.length <= 104
s 由小写英文字母组成
来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/remove-duplicate-letters
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
* */
public class 去除重复字母_316 {
    public static void main(String[] args) {
        去除重复字母_316 demo = new 去除重复字母_316();
        String s = "cbacdcbc"; // bcabc cbacdcbc  abacb
        String cbacdcbc = demo.removeDuplicateLetters(s);
        System.out.println(cbacdcbc);
    }

    /*
    * 解题思路： 要返回结果的字典序最小，顺序也不能变
    *  去除重复的字母----> 如何去除 保证字典序最小  尽可能让小的字母在前面呗
    *  利用单调栈，保证 接下来要插入栈中的元素 小于当前栈顶元素
    *  如果不小于，且栈顶元素为重复元素，则将栈顶元素出栈， 直到 当前元素 大于栈顶元素
    * */
    public String removeDuplicateLetters(String s) {
        LinkedList<Character> stack = new LinkedList<>();
        int[] wordNums = new int[26];
        // 开始记录 重复字母
        int length = s.length();
        for(int i =0;i<length; i++){
            wordNums[s.charAt(i) - 'a'] ++;
        }
        stack.push(s.charAt(0));
        int index = 1;
        while(index<length){
            Character c = s.charAt(index);
            if(stack.contains(c)){
                wordNums[c-'a'] --;
                index ++ ;
                continue;
            }
            // 若当前元素 小于栈顶元素，且栈顶元素为重复元素，则将栈底元素出栈
            Character top = stack.peek();
            while(!stack.isEmpty() && c<=top && wordNums[top-'a']>1){
                stack.pop();
                wordNums[top-'a'] --;
                top = stack.peek();
            }
            // 入栈
            stack.push(c);
            index++;
        }
        // 处理一下重复元素
        StringBuilder result = new StringBuilder();
        while(!stack.isEmpty()){
            Character c = stack.pollLast();
            result.append(c);
        }
        return result.toString();
    }
}
